package com.bank.backend.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bank.backend.exception.BusinessException;
import com.bank.backend.enums.ErrorCode;
import com.bank.backend.mapper.CardMapper;
import com.bank.backend.mapper.DepositMapper;
import com.bank.backend.mapper.UserMapper;
import com.bank.backend.model.dto.CardCreateDTO;
import com.bank.backend.model.dto.CardQueryDTO;
import com.bank.backend.model.dto.CardPasswordUpdateDTO;
import com.bank.backend.model.entity.Card;
import com.bank.backend.model.entity.Deposit;
import com.bank.backend.model.entity.User;
import com.bank.backend.model.vo.CardVO;
import com.bank.backend.model.vo.UserVO;
import com.bank.backend.result.PageResult;
import com.bank.backend.service.CardManageService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import cn.hutool.crypto.digest.MD5;
import java.time.LocalDate;

/**
 * 银行卡管理服务实现类
 */
@Service
@Slf4j
public class CardManageServiceImpl extends ServiceImpl<CardMapper, Card> implements CardManageService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private DepositMapper depositMapper;

    @Resource
    private CardMapper cardMapper;

    @Override
    @Transactional
    public void createCard(CardCreateDTO cardCreateDTO) {
        // 1. 根据身份证号查询客户信息
        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.eq("pid", cardCreateDTO.getPid());
        User user = userMapper.selectOne(userQueryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "客户不存在，请先注册客户信息");
        }
        // 2. 验证存款产品类型是否存在
        Deposit deposit = depositMapper.selectById(cardCreateDTO.getDepositId());
        if (deposit == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "存款产品类型不存在");
        }
        // 3. 验证开户金额
        if (cardCreateDTO.getOpenMoney() < 1.0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "开户金额不能低于1元");
        }
        // 4. 生成唯一银行卡号（16位数字）
        String cardId = generateCardId();
        // 5. 创建银行卡记录
        Card card = new Card();
        card.setCardId(cardId);
        card.setUserId(user.getUserId());
        card.setDepositId(cardCreateDTO.getDepositId());
        card.setCurrency(cardCreateDTO.getCurrency());
        card.setOpenDate(LocalDateTime.now());
        card.setOpenMoney(BigDecimal.valueOf(cardCreateDTO.getOpenMoney()));
        card.setUpdateTime(LocalDateTime.now());
        card.setCreateTime(LocalDateTime.now());
        card.setBalance(BigDecimal.valueOf(cardCreateDTO.getOpenMoney())); // 初始余额等于开户金额
        // 保存到数据库
        boolean success = save(card);
        if (!success) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "银行卡创建失败");
        }
      return;
    }

    @Override
    public CardVO getCardByCardId(String cardId) {
        Card card = getById(cardId);
        if (card == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "银行卡不存在");
        }
        CardVO cardVO = new CardVO();
        BeanUtils.copyProperties(card, cardVO);
        User user = userMapper.selectById(card.getUserId());
        cardVO.setUserName(user != null ? user.getUserName() : null);
        cardVO.setIsReportLoss(card.getIsReportLoss() == null ? 0 : card.getIsReportLoss());
        return cardVO;
    }

    @Override
    public UserVO getCustomerInfoByPid(String pid) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", pid);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "客户不存在");
        }
        UserVO vo = new UserVO();
        BeanUtils.copyProperties(user, vo);
        return vo;
    }

    @Override
    public PageResult<CardVO> pageCardList(Integer page, Integer size, Integer userId, String cardId, Integer isReportLoss) {
        Page<Card> pageObj = new Page<>(page == null ? 1 : page, size == null ? 10 : size);
        QueryWrapper<Card> wrapper = new QueryWrapper<>();
        if (userId != null) wrapper.eq("user_id", userId);
        if (cardId != null && !cardId.isEmpty()) wrapper.eq("card_id", cardId);
        if (isReportLoss != null) wrapper.eq("is_report_loss", isReportLoss);
        Page<Card> cardPage = cardMapper.selectPage(pageObj, wrapper);
        List<CardVO> voList = new ArrayList<>();
        for (Card card : cardPage.getRecords()) {
            CardVO vo = new CardVO();
            BeanUtils.copyProperties(card, vo);
            vo.setIsReportLoss(card.getIsReportLoss() == null ? 0 : card.getIsReportLoss());
            // 获取存款业务信息
            if (card.getDepositId() != null) {
                Deposit deposit = depositMapper.selectById(card.getDepositId());
                if (deposit != null) {
                    vo.setDepositName(deposit.getDepositName());
                }
            }
            voList.add(vo);
        }
        PageResult<CardVO> result = new PageResult<>();
        result.setTotal(cardPage.getTotal());
        result.setPage((int) cardPage.getCurrent());
        result.setSize((int) cardPage.getSize());
        result.setRecords(voList);
        return result;
    }

    @Override
    @Transactional
    public void updateReportLossStatus(String cardId, Integer isReportLoss) {
        Card card = cardMapper.selectById(cardId);
        if (card == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "银行卡不存在");
        }
        if (isReportLoss == null || (isReportLoss != 0 && isReportLoss != 1)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        card.setIsReportLoss(isReportLoss);
        boolean success = cardMapper.updateById(card) > 0;
        if (!success) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "操作失败");
        }
    }

    @Override
    public PageResult<CardVO> pageList(CardQueryDTO queryDTO) {
        Page<Card> pageObj = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        LambdaQueryWrapper<Card> wrapper = new LambdaQueryWrapper<>();
        
        // 用户ID查询
        if (queryDTO.getUserId() != null) {
            wrapper.eq(Card::getUserId, queryDTO.getUserId());
        }
        
        // 银行卡号查询
        if (queryDTO.getCardId() != null && !queryDTO.getCardId().trim().isEmpty()) {
            wrapper.like(Card::getCardId, queryDTO.getCardId().trim());
        }
        
        // 货币类型查询
        if (queryDTO.getCurrency() != null && !queryDTO.getCurrency().trim().isEmpty()) {
            wrapper.eq(Card::getCurrency, queryDTO.getCurrency().trim());
        }
        
        // 存款类型查询
        if (queryDTO.getDepositId() != null) {
            wrapper.eq(Card::getDepositId, queryDTO.getDepositId());
        }
        
        // 挂失状态查询
        if (queryDTO.getIsReportLoss() != null) {
            wrapper.eq(Card::getIsReportLoss, queryDTO.getIsReportLoss());
        }
        
        // 余额范围查询
        if (queryDTO.getMinBalance() != null) {
            wrapper.ge(Card::getBalance, queryDTO.getMinBalance());
        }
        if (queryDTO.getMaxBalance() != null) {
            wrapper.le(Card::getBalance, queryDTO.getMaxBalance());
        }
        
        wrapper.eq(Card::getIsDeleted, 0);
        wrapper.orderByDesc(Card::getCreateTime);
        
        Page<Card> cardPage = this.page(pageObj, wrapper);
        ArrayList<CardVO> voList = new ArrayList<>();
        for (Card card : cardPage.getRecords()) {
            CardVO vo = new CardVO();
            BeanUtils.copyProperties(card, vo);
            vo.setIsReportLoss(card.getIsReportLoss() == null ? 0 : card.getIsReportLoss());
            // 获取存款业务信息
            if (card.getDepositId() != null) {
                Deposit deposit = depositMapper.selectById(card.getDepositId());
                if (deposit != null) {
                    vo.setDepositName(deposit.getDepositName());
                }
            }
            voList.add(vo);
        }
        PageResult<CardVO> result = new PageResult<>();
        result.setTotal(cardPage.getTotal());
        result.setPage((int) cardPage.getCurrent());
        result.setSize((int) cardPage.getSize());
        result.setRecords(voList);
        return result;
    }

    @Override
    @Transactional
    public void updateCardPassword(CardPasswordUpdateDTO passwordUpdateDTO) {
        if (passwordUpdateDTO == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码修改参数不能为空");
        }
        String oldPassword = passwordUpdateDTO.getOldPassword();
        //验证新密码格式
        String newPassword = passwordUpdateDTO.getNewPassword();
        if (newPassword == null || !newPassword.matches("^\\d{6}$")) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "新密码必须是6位数字");
        }
        //验证新密码不能与原密码相同
        if (newPassword.equals(oldPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "新密码不能与原密码相同");
        }
        //查询银行卡信息
        String cardId = passwordUpdateDTO.getCardId();
        Card card = cardMapper.selectById(cardId);

        //验证原密码是否正确
        String oldPasswordMd5 = MD5.create().digestHex(oldPassword);
        if (!oldPasswordMd5.equals(card.getPassword())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "原密码错误");
        }
        //加密新密码并更新
        String newPasswordMd5 = MD5.create().digestHex(newPassword);
        card.setPassword(newPasswordMd5);
        card.setUpdateTime(LocalDateTime.now());
        boolean success = cardMapper.updateById(card) > 0;
        if (!success) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "密码修改失败");
        }
    }

    @Override
    public PageResult<CardVO> pageCardList(CardQueryDTO queryDTO) {
        Page<Card> pageObj = new Page<>(queryDTO.getPage(), queryDTO.getSize());
        LambdaQueryWrapper<Card> wrapper = new LambdaQueryWrapper<>();
        
        // 用户ID查询
        if (queryDTO.getUserId() != null) {
            wrapper.eq(Card::getUserId, queryDTO.getUserId());
        }
        
        // 银行卡号查询
        if (queryDTO.getCardId() != null && !queryDTO.getCardId().trim().isEmpty()) {
            wrapper.eq(Card::getCardId, queryDTO.getCardId().trim());
        }
        
        // 货币类型查询
        if (queryDTO.getCurrency() != null && !queryDTO.getCurrency().trim().isEmpty()) {
            wrapper.eq(Card::getCurrency, queryDTO.getCurrency().trim());
        }
        
        // 存款类型查询
        if (queryDTO.getDepositId() != null) {
            wrapper.eq(Card::getDepositId, queryDTO.getDepositId());
        }
        
        // 挂失状态查询
        if (queryDTO.getIsReportLoss() != null) {
            wrapper.eq(Card::getIsReportLoss, queryDTO.getIsReportLoss());
        }
        
        // 余额范围查询
        if (queryDTO.getMinBalance() != null) {
            wrapper.ge(Card::getBalance, queryDTO.getMinBalance());
        }
        if (queryDTO.getMaxBalance() != null) {
            wrapper.le(Card::getBalance, queryDTO.getMaxBalance());
        }
        
        // 时间范围查询
        if (queryDTO.getStartTime() != null && !queryDTO.getStartTime().trim().isEmpty()) {
            try {
                log.info("Parsing startTime: {}", queryDTO.getStartTime().trim());
                LocalDate startDate = LocalDate.parse(queryDTO.getStartTime().trim());
                LocalDateTime startDateTime = LocalDateTime.of(startDate, LocalTime.MIN);
                wrapper.ge(Card::getCreateTime, startDateTime);
                log.info("Parsed startDateTime: {}", startDateTime);
            } catch (Exception e) {
                log.error("Error parsing startTime: {}", queryDTO.getStartTime(), e);
            }
        }
        if (queryDTO.getEndTime() != null && !queryDTO.getEndTime().trim().isEmpty()) {
            try {
                log.info("Parsing endTime: {}", queryDTO.getEndTime().trim());
                LocalDate endDate = LocalDate.parse(queryDTO.getEndTime().trim());
                LocalDateTime endDateTime = LocalDateTime.of(endDate, LocalTime.MAX);
                wrapper.le(Card::getCreateTime, endDateTime);
                log.info("Parsed endDateTime: {}", endDateTime);
            } catch (Exception e) {
                log.error("Error parsing endTime: {}", queryDTO.getEndTime(), e);
            }
        }
        
        wrapper.eq(Card::getIsDeleted, 0);
        wrapper.orderByDesc(Card::getCreateTime);
        
        Page<Card> cardPage = this.page(pageObj, wrapper);
        ArrayList<CardVO> voList = new ArrayList<>();
        for (Card card : cardPage.getRecords()) {
            CardVO vo = new CardVO();
            BeanUtils.copyProperties(card, vo);
            vo.setIsReportLoss(card.getIsReportLoss() == null ? 0 : card.getIsReportLoss());
            // 获取存款业务信息
            if (card.getDepositId() != null) {
                Deposit deposit = depositMapper.selectById(card.getDepositId());
                if (deposit != null) {
                    vo.setDepositName(deposit.getDepositName());
                }
            }
            voList.add(vo);
        }
        PageResult<CardVO> result = new PageResult<>();
        result.setTotal(cardPage.getTotal());
        result.setPage((int) cardPage.getCurrent());
        result.setSize((int) cardPage.getSize());
        result.setRecords(voList);
        return result;
    }

    /**
     * 生成银行卡号（16位数字）
     */
    private String generateCardId() {
        Random random = new Random();
        StringBuilder cardId = new StringBuilder();
        
        // 生成16位随机数字
        for (int i = 0; i < 16; i++) {
            cardId.append(random.nextInt(10));
        }
        return cardId.toString();
    }

    @Override
    @Transactional
    public String removeCard(String cardId) {
        Card card = this.getById(cardId);
        if (card == null || card.getIsDeleted() == 1) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "银行卡不存在");
        }

        // 检查银行卡余额，如果余额大于1元则不允许删除
        if (card.getBalance().compareTo(BigDecimal.ONE) > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "银行卡余额大于1元，无法删除");
        }

        // 逻辑删除银行卡
        boolean result = this.removeById(cardId);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除银行卡失败");
        }

        log.info("银行卡{}删除成功", cardId);
        return "银行卡删除成功";
    }
} 